﻿using System;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using StockLib;

namespace StockUI
{
    public partial class FormKey : FormAbstract
    {
        public event FormKeySelectedEventHandler Selected;

        public string InitChars { get; set; }

        public bool AutoClose { get; set; }

        public FormKey()
        {
            InitializeComponent();

            this.StartPosition = FormStartPosition.Manual;
            this.AutoClose = true;
            this.InitChars = string.Empty;
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Escape:
                    this.Close();
                    return true;

                case Keys.Enter:
                    if (listStock.SelectedItem != null)
                    {
                        Stock stock = listStock.SelectedItem as Stock;
                        OnSelected(this, new FormKeySelectedEventArgs(stock));
                    }
                    if (AutoClose)
                    {
                        this.Close();
                    }
                    return true;

                case Keys.Up:
                    if (listStock.Items.Count > 1)
                    {
                        listStock.SelectedIndex = (listStock.SelectedIndex + listStock.Items.Count - 1) % listStock.Items.Count;
                    }
                    return true;

                case Keys.Down:
                    if (listStock.Items.Count > 1)
                    {
                        listStock.SelectedIndex = (listStock.SelectedIndex + 1) % listStock.Items.Count;
                    }
                    return true;
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }


        private void FormKey_Load(object sender, EventArgs e)
        {
            txtInput.CharacterCasing = CharacterCasing.Upper;
            txtInput.Focus();
            if (!string.IsNullOrEmpty(InitChars))
                txtInput.AppendText(InitChars);
            else
                BindDataSource();
        }

        private void FormKey_FormClosing(object sender, FormClosingEventArgs e)
        {
            suppressBind = true;
            txtInput.Text = string.Empty;
            suppressBind = false;
        }

        private void FormKey_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Regex.IsMatch(e.KeyChar.ToString(), "^[^0-9A-Za-z?\n\b]$"))
            {
                e.Handled = true;
            }
        }
        
        private void txtInput_TextChanged(object sender, EventArgs e)
        {
            BindDataSource();
        }

        private bool suppressBind = false;
        private void BindDataSource()
        {
            if (!suppressBind)
            {
                listStock.DataSource = StockContainer.Instance.Values.Where(s => Regex.IsMatch(s.ShortName, "^" + txtInput.Text) || Regex.IsMatch(s.Code, "^" + txtInput.Text)).ToList();
            }
        }

        private void listStock_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            SendKeys.Send("{ENTER}");
        }

        private void listStock_DrawItem(object sender, DrawItemEventArgs e)
        {
            Stock stock = listStock.Items[e.Index] as Stock;
            string text = string.Format("{0} {1}", stock.Code, stock.Name);
            if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
            {
                e.Graphics.FillRectangle(Brushes.DarkBlue, e.Bounds);
                TextRenderer.DrawText(e.Graphics, text, listStock.Font, e.Bounds, Color.White, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
            }
            else
            {
                e.DrawBackground();
                TextRenderer.DrawText(e.Graphics, text, listStock.Font, e.Bounds, listStock.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
            }
        }

        protected void OnSelected(object sender, FormKeySelectedEventArgs e)
        {
            if (Selected != null)
            {
                Selected(sender, e);
            }
        }
    }

    public class FormKeySelectedEventArgs : EventArgs
    {
        private Stock stock;

        public Stock Stock
        {
            get
            {
                return stock;
            }
        }

        public FormKeySelectedEventArgs(Stock stock)
        {
            this.stock = stock;
        }
    }

    public delegate void FormKeySelectedEventHandler(object sender, FormKeySelectedEventArgs e);
}
